package com.whfc.hdc.service.impl;

import com.whfc.common.enums.EnableState;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ResultEnum;
import com.whfc.hdc.dao.AlgDeviceConfigMapper;
import com.whfc.hdc.dao.AlgDeviceStreamMapper;
import com.whfc.hdc.dao.AlgStreamConfigMapper;
import com.whfc.hdc.dto.AlgDeviceConfigDetailDTO;
import com.whfc.hdc.dto.AlgDeviceStreamConfigDTO;
import com.whfc.hdc.dto.AlgDeviceStreamDTO;
import com.whfc.hdc.entity.AlgDeviceStream;
import com.whfc.hdc.entity.AlgStreamConfig;
import com.whfc.hdc.enums.AlgConfigCode;
import com.whfc.hdc.params.AlgDeviceStreamConfigAddParam;
import com.whfc.hdc.params.AlgDeviceStreamConfigEditParam;
import com.whfc.hdc.params.AlgDeviceStreamParam;
import com.whfc.hdc.params.AlgTypeParam;
import com.whfc.hdc.service.AlgDeviceStreamService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * @author qzexing
 * @version 1.0
 * @date 2021-08-02 15:25
 */
@DubboService(interfaceClass = AlgDeviceStreamService.class, version = "1.0.0")
public class AlgDeviceStreamServiceImpl implements AlgDeviceStreamService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private AlgDeviceStreamMapper algDeviceStreamMapper;

    @Autowired
    private AlgStreamConfigMapper algStreamConfigMapper;

    @Autowired
    private AlgDeviceConfigMapper algDeviceConfigMapper;

    @Override
    public List<AlgDeviceStreamDTO> list(String sn) {
        logger.info("获取算法盒子视频流地址列表, sn:{}", sn);
        return algDeviceStreamMapper.selectBySn(sn);
    }

    @Override
    public void add(AlgDeviceStreamParam param) {
        logger.info("新增算法盒子视频流地址, param:{}", param);
        AlgDeviceStream deviceStream = new AlgDeviceStream();
        deviceStream.setSn(param.getSn());
        deviceStream.setName(param.getName());
        deviceStream.setStreamUrl(param.getStreamUrl());
        algDeviceStreamMapper.insertSelective(deviceStream);
    }

    @Override
    public void edit(AlgDeviceStreamParam param) {
        logger.info("编辑算法盒子视频流地址, param:{}", param);
        Integer streamId = param.getStreamId();
        AlgDeviceStream deviceStream = algDeviceStreamMapper.selectByPrimaryKey(streamId);
        if (deviceStream == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该视频流地址不存在");
        }
        deviceStream.setName(param.getName());
        deviceStream.setStreamUrl(param.getStreamUrl());
        algDeviceStreamMapper.updateByPrimaryKeySelective(deviceStream);
    }

    @Override
    public void del(Integer streamId) {
        logger.info("删除算法盒子视频流地址, streamId:{}", streamId);
        algDeviceStreamMapper.logicDel(streamId);
    }

    @Override
    public List<AlgDeviceStreamConfigDTO> configList(Integer streamId) {
        logger.info("获取算法盒子视频流算法配置列表, streamId:{}", streamId);
        return algStreamConfigMapper.selectByStreamId(streamId);
    }

    @Override
    public void configAdd(AlgDeviceStreamConfigAddParam param) {
        logger.info("新增算法盒子视频流算法配置, param:{}", param);
        Integer streamId = param.getStreamId();
        List<AlgTypeParam> algTypeList = param.getAlgTypeList();
        for (AlgTypeParam algTypeParam : algTypeList) {
            Integer algType = algTypeParam.getAlgType();
            AlgStreamConfig algStreamConfig = algStreamConfigMapper.selectByStreamIdAndAlgType(streamId, algType);
            if (algStreamConfig != null) {
                throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该视频该算法类型已存在");
            }
            algStreamConfig = new AlgStreamConfig();
            algStreamConfig.setStreamId(streamId);
            algStreamConfig.setAlgType(algType);
            algStreamConfig.setAlgTypeName(algTypeParam.getAlgTypeName());
            algStreamConfigMapper.insertSelective(algStreamConfig);
        }
    }

    @Override
    public void configEdit(AlgDeviceStreamConfigEditParam param) {
        logger.info("编辑算法盒子视频流算法配置, param:{}", param);
        AlgStreamConfig algStreamConfig = algStreamConfigMapper.selectByPrimaryKey(param.getId());
        if (algStreamConfig == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该视频该算法配置不存在");
        }
        String configs = param.getConfigs();
        if (StringUtils.isNotBlank(configs)) {
            algStreamConfig.setConfigs(configs);
        }
        String params = param.getParams();
        if (StringUtils.isNotBlank(params)) {
            algStreamConfig.setParams(params);
        }
        Integer state = param.getState();
        if (state != null) {
            algStreamConfig.setState(state);
        }
        algStreamConfigMapper.updateByPrimaryKeySelective(algStreamConfig);
    }

    @Override
    public void configDel(Integer id) {
        logger.info("删除算法盒子视频流算法配置, id:{}", id);
        algStreamConfigMapper.logicDel(id);
    }

    @Override
    public AlgDeviceConfigDetailDTO getDeviceStreamConfigDetail(String sn) {
        AlgDeviceConfigDetailDTO configDetailDTO = new AlgDeviceConfigDetailDTO();
        //获取推流地址
        List<String> pushUrl = algDeviceConfigMapper.selectConfigList(sn, AlgConfigCode.PUSH_URL.getCode());
        configDetailDTO.setPushUrlList(pushUrl);
        //获取视频流地址
        List<AlgDeviceStreamDTO> streamList = algDeviceStreamMapper.selectBySn(sn);
        for (AlgDeviceStreamDTO stream : streamList) {
            //获取每个视频流的配置
            stream.setStreamId(null);
            stream.setSn(null);
            List<AlgDeviceStreamConfigDTO> list = algStreamConfigMapper.selectByStreamId(stream.getStreamId());
            List<AlgDeviceStreamConfigDTO> streamConfigList = new ArrayList<>();
            for (AlgDeviceStreamConfigDTO streamConfig : list) {
                if (EnableState.ENABLED.getValue().equals(streamConfig.getState())) {
                    streamConfig.setId(null);
                    streamConfig.setAlgTypeName(null);
                    streamConfig.setState(null);
                    streamConfigList.add(streamConfig);
                }
            }
            stream.setStreamConfigList(streamConfigList);
        }
        configDetailDTO.setStreamList(streamList);
        return configDetailDTO;
    }
}
